<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>let-const的基本使用</title>
  <!-- 
  在JavaScript中， `let`  和  `const`  是 ES6 引入的关键字，用于声明变量。它们相较于传统的  `var`  关键字有一些显著的特点和优势。
  1.  `let`  的基本使用
   1.1 声明变量
  `let`  用于声明一个块级作用域的变量，这意味着它的作用域仅限于声明它的代码块内。
  {
      let x = 10;
      console.log(x); // 输出: 10
  }
  console.log(x); // 报错: x is not defined
   1.2 变量提升
  使用  `let`  声明的变量会发生“暂时性死区”（Temporal Dead Zone），即在声明之前无法访问。
  console.log(y); // 报错: Cannot access 'y' before initialization
  let y = 20;
   1.3 重复声明
  在同一作用域内，使用  `let`  不能重复声明同一个变量。
  let z = 30;
  // let z = 40; // 报错: Identifier 'z' has already been declared
  2.  `const`  的基本使用
   2.1 声明常量
  `const`  用于声明一个常量，声明时必须初始化，并且其值在后续不能被重新赋值。
  const PI = 3.14;
  console.log(PI); // 输出: 3.14
  // PI = 3.14159; // 报错: Assignment to constant variable.
   2.2 块级作用域
  `const`  也具有块级作用域，与  `let`  相同。
  {
      const a = 50;
      console.log(a); // 输出: 50
  }
  console.log(a); // 报错: a is not defined
   2.3 对象和数组的可变性
  虽然  `const`  声明的变量不能重新赋值，但如果它是一个对象或数组，仍然可以修改其属性或元素。
  const obj = { name: 'Alice' };
  obj.name = 'Bob'; // 允许
  console.log(obj.name); // 输出: Bob

  const arr = [1, 2, 3];
  arr.push(4); // 允许
  console.log(arr); // 输出: [1, 2, 3, 4]
  3. 总结
  - 作用域： `let`  和  `const`  都是块级作用域，而  `var`  是函数级作用域。
  - 提升： `let`  和  `const`  都会导致“暂时性死区”，在声明之前无法访问。
  - 重新赋值： `let`  声明的变量可以重新赋值，而  `const`  声明的变量一旦赋值后不能再改变。
  - 可变性： `const`  声明的对象和数组的属性或元素是可以改变的，但不能重新赋值。
   -->
</head>
<body>

  <script>
    // ES6之前的作用域
    var a = 10;
    a = 20;
    a = 30;
    console.log(a); // 输出: 30
    
    // ES6之后的作用域
    // 1.  `let`  的基本使用
    // 1.1 声明变量
    let b = 10;
    b = 20;
    b = 30;
    console.log(b); // 输出: 30
    // 1.2 块级作用域
    {
        let c = 40;
        console.log(c); // 输出: 40
    }
    // console.log(c); // 报错: c is not defined

    // 2.  `const`  的基本使用
    // 2.1 声明常量
    const d = 50;
    // d = 60; // 报错: Assignment to constant variable.
    console.log(d); // 输出: 50
    // 2.2 块级作用域
    {
        const e = 70;
        console.log(e); // 输出: 70
    }
    // console.log(e); // 报错: e is not defined

    // 2.1 赋值引用类型
    const obj = { name: 'Bob' };
    obj.name = 'Alice';
    console.log(obj.name); // 输出: Alice

    const arr = [1, 2, 3];
    arr.push(4);
    console.log(arr); // 输出: [1, 2, 3, 4]

  </script>
  
</body>
</html>